﻿using FlyingEye.Common.Utils;
using FlyingEye.ESApplication.Services;
using FlyingEye.Exceptions;
using FlyingEye.LogInformations;
using FlyingEye.MySqlApplication;
using FlyingEye.MySqlApplication.Models;
using FlyingEye.Users;
using FlyingEye.Users.Exceptions;
using FlyingEye.Users.Models;
using Microsoft.AspNetCore.Http;
using System.Security.Claims;
using Volo.Abp.ObjectMapping;

namespace FlyingEye.Services
{
    internal class UserService : IUserService
    {
        private readonly IJwtBearerService _jwtService;

        private readonly IUserRepository _repository;

        private readonly IObjectMapper _mapper;

        private readonly ApplicationConfiguration _application;

        private readonly IHttpContextAccessor _httpContextAccessor;

        private readonly ILogService _logService;

        public UserService(IUserRepository repository,
            IObjectMapper mapper,
            ApplicationConfiguration application,
            IJwtBearerService jwtService,
            IHttpContextAccessor accessor,
            ILogService logService)
        {
            _logService = logService;
            _httpContextAccessor = accessor;
            _application = application;
            _repository = repository;
            _mapper = mapper;
            _jwtService = jwtService;
        }

        public async Task<User> GetUserByIdAsync(Guid userId)
        {
            return _mapper.Map<UserModel, User>(await _repository.FindAsync(userId));
        }

        /// <summary>
        /// 管理员专用注册用户接口
        /// </summary>
        public async Task RegisterUserAsync(string creationUserName, User newUser)
        {
            var user = await _repository.GetUserByNameAsync(creationUserName);

            if (user == null)
            {
                throw new InvalidOperationException($"无效的用户名{creationUserName}。");
            }

            if (user.Permission != UserPermissions.Admin)
            {
                throw new InvalidOperationException($"{creationUserName} 用户没有权限执行此操作。");
            }

            var userModel = new UserModel(user.Id, newUser.UserName, newUser.Password, newUser.Permission);

            await _repository.AddUserAsync(userModel);
        }

        public async Task RegisterUserAsync(User newUser)
        {
            if (newUser.Permission == UserPermissions.Admin)
            {
                throw new InvalidOperationException($"没有权限注册 Admin 权限的用户。");
            }

            var userModel = _mapper.Map<User, UserModel>(newUser);

            await _repository.AddUserAsync(userModel);

            var userId = _httpContextAccessor.HttpContext?.User.FindFirst(ClaimTypes.NameIdentifier)?.Value;

            if (Guid.TryParse(userId, out var id))
            {
                var creator = await GetUserByIdAsync(id);
                await _logService.LogUserCreationInformation(new UserCreationInformation(id, creator.UserName, userModel.Id, userModel.UserName));
            }
        }

        public async Task UnregisterUserByNameAsync(string name)
        {
            await _repository.DeleteUserByNameAsync(name);
        }

        public async Task UpdateUserNameAsnyc(User user, string newName)
        {
            var oldUser = await _repository.GetUserByNameAsync(user.UserName);

            if (oldUser == null)
            {
                throw new UserNotExistException($"用户 {user.UserName} 不存在。");
            }

            if (!string.Equals(user.UserName, newName, StringComparison.OrdinalIgnoreCase))
            {
                oldUser.UserName = newName;
                await _repository.UpdateUserAsync(oldUser);
            }
        }

        public async Task UpdateUserPasswordAsync(User user, string newPassword)
        {
            var oldUser = await _repository.GetUserByNameAsync(user.UserName);

            if (oldUser == null)
            {
                throw new UserNotExistException($"用户 {user.UserName} 不存在。");
            }

            if (!string.Equals(user.Password, newPassword, StringComparison.OrdinalIgnoreCase))
            {
                oldUser.Password = newPassword;
                await _repository.UpdateUserAsync(oldUser);
            }
        }

        public async Task<string> LoginForeverAsync(LoginUser user)
        {
            var userModel = await _repository.GetUserByNameAsync(user.UserName);

            if (userModel == null)
            {
                throw new UserNotExistException($"用户 {user.UserName} 不存在。");
            }

            var userPassword = _application.ConvertFromEncryptedBase64String(user.Password);
            var userModelPassword = _application.ConvertFromEncryptedBase64String(userModel.Password);

            if (!(userModel.Permission == UserPermissions.Admin || userModel.Permission == UserPermissions.ME))
            {
                throw new UserPermissionDeniedException();
            }

            if (userPassword != userModelPassword)
            {
                throw new LoginFailedException();
            }

            return _jwtService.GenerateJwtTokenForever(userModel);
        }

        public async Task<string> LoginAsync(LoginUser user, TimeSpan timeSpan)
        {
            var userModel = await _repository.GetUserByNameAsync(user.UserName);

            if (userModel == null)
            {
                throw new UserNotExistException($"用户 {user.UserName} 不存在。");
            }

            var userPassword = _application.ConvertFromEncryptedBase64String(user.Password);
            var userModelPassword = _application.ConvertFromEncryptedBase64String(userModel.Password);

            if (userPassword != userModelPassword)
            {
                throw new LoginFailedException();
            }

            return _jwtService.GenerateJwtToken(userModel, timeSpan);
        }
    }
}
